/**
 * @file demo_alarmengine_usage.cpp
 * @brief 报警引擎使用演示程序
 *
 * 演示功能：
 * 1. 初始化报警引擎并配置阈值
 * 2. 模拟电表数据变化触发报警
 * 3. 测试报警去重机制
 * 4. 测试报警恢复检测
 * 5. 查询报警记录
 * 6. 报警确认功能
 */

#include <QCoreApplication>
#include <QTimer>
#include <QDebug>
#include "../src/core/alarmengine.h"
#include "../src/core/meter.h"
#include "../src/database/dbmanager.h"
#include "../src/utils/logger.h"

class AlarmEngineDemo : public QObject
{
    Q_OBJECT

public:
    AlarmEngineDemo(QObject *parent = nullptr)
        : QObject(parent), m_step(0)
    {
    }

    void start()
    {
        qInfo() << "========================================";
        qInfo() << "报警引擎演示程序";
        qInfo() << "========================================\n";

        // 初始化日志系统（使用绝对路径）
        QString logPath = "C:/Users/86188/Desktop/ModbusPro/QModbusPowerCloud/logs/demo_alarmengine.log";
        Logger::instance()->initialize(logPath, LogLevel::Debug);
        Logger::instance()->info("演示程序启动");

        // 初始化数据库
        qInfo() << "[步骤 1] 初始化数据库...";
        if (!DBManager::instance()->initialize())
        {
            qCritical() << "数据库初始化失败！";
            QCoreApplication::quit();
            return;
        }
        qInfo() << "数据库初始化成功\n";

        // 创建报警引擎
        qInfo() << "[步骤 2] 创建报警引擎...";
        m_alarmEngine = new AlarmEngine(DBManager::instance(), this);

        // 配置阈值
        AlarmThreshold threshold;
        threshold.voltageDropThreshold = 200.0;  // 电压跌落阈值：200V
        threshold.underVoltageThreshold = 198.0; // 欠压阈值：198V
        threshold.overVoltageThreshold = 245.0;  // 过压阈值：245V
        threshold.overCurrentThreshold = 50.0;   // 过流阈值：50A
        m_alarmEngine->setThreshold(threshold);
        qInfo() << "报警阈值配置：";
        qInfo() << "  - 电压跌落: " << threshold.voltageDropThreshold << "V";
        qInfo() << "  - 欠压: " << threshold.underVoltageThreshold << "V";
        qInfo() << "  - 过压: " << threshold.overVoltageThreshold << "V";
        qInfo() << "  - 过流: " << threshold.overCurrentThreshold << "A\n";

        // 连接报警信号
        connect(m_alarmEngine, &AlarmEngine::alarmTriggered,
                this, &AlarmEngineDemo::onAlarmTriggered);
        connect(m_alarmEngine, &AlarmEngine::alarmRecovered,
                this, &AlarmEngineDemo::onAlarmRecovered);

        // 启动报警引擎
        m_alarmEngine->start();
        qInfo() << "报警引擎已启动\n";

        // 创建测试电表
        qInfo() << "[步骤 3] 创建测试电表...";
        m_meter1 = new Meter(1, "配电室A-1号表", "1号柜", 1, this);
        m_meter2 = new Meter(25, "配电室B-25号表", "25号柜", 2, this);

        // 设置电表为在线状态（重要！）
        m_meter1->setOnline(true);
        m_meter2->setOnline(true);

        // 保存电表信息到数据库（满足外键约束）
        MeterInfo info1;
        info1.meterId = 1;
        info1.name = "配电室A-1号表";
        info1.location = "1号柜";
        info1.busId = 1;
        info1.enabled = true;
        info1.createTime = QDateTime::currentDateTime();
        info1.updateTime = QDateTime::currentDateTime();
        DBManager::instance()->saveMeterInfo(info1);

        MeterInfo info2;
        info2.meterId = 25;
        info2.name = "配电室B-25号表";
        info2.location = "25号柜";
        info2.busId = 2;
        info2.enabled = true;
        info2.createTime = QDateTime::currentDateTime();
        info2.updateTime = QDateTime::currentDateTime();
        DBManager::instance()->saveMeterInfo(info2);

        qInfo() << "已保存电表信息到数据库";

        // 添加到报警引擎监控
        m_alarmEngine->addMeter(m_meter1);
        m_alarmEngine->addMeter(m_meter2);
        qInfo() << "已添加2个测试电表到监控（在线状态）\n";

        // 启动模拟测试
        QTimer::singleShot(1000, this, &AlarmEngineDemo::runStep);
    }

private slots:
    void onAlarmTriggered(const AlarmEvent &event)
    {
        qWarning() << "【报警触发】" << event.description();
        qWarning() << "  报警ID: " << event.alarmId;
        qWarning() << "  电表: " << event.meterName;
        qWarning() << "  类型: " << event.typeName;
        qWarning() << "  当前值: " << event.value;
        qWarning() << "  阈值: " << event.threshold;
        qWarning() << "  时间: " << event.timestamp.toString("yyyy-MM-dd HH:mm:ss");
        qWarning() << "";
    }

    void onAlarmRecovered(int meterId, AlarmType type)
    {
        qInfo() << "【报警恢复】电表" << meterId << "-" << AlarmEngine::getAlarmTypeName(type);
        qInfo() << "";
    }

    void runStep()
    {
        m_step++;

        switch (m_step)
        {
        case 1:
            // 步骤1：正常数据
            qInfo() << "========================================";
            qInfo() << "[测试场景 1] 设置正常电压电流数据";
            qInfo() << "========================================";
            m_meter1->setUa(220.0);
            m_meter1->setUb(221.0);
            m_meter1->setUc(219.0);
            m_meter1->setIa(15.0);
            m_meter1->setIb(14.8);
            m_meter1->setIc(15.2);
            emit m_meter1->dataUpdated();

            qInfo() << "电表1数据：Ua=220V, Ub=221V, Uc=219V, Ia=15A, Ib=14.8A, Ic=15.2A";
            qInfo() << "预期：无报警\n";

            QTimer::singleShot(2000, this, &AlarmEngineDemo::runStep);
            break;

        case 2:
            // 步骤2：电压跌落
            qInfo() << "========================================";
            qInfo() << "[测试场景 2] 模拟A相电压跌落";
            qInfo() << "========================================";
            m_meter1->setUa(180.0); // 低于200V阈值
            emit m_meter1->dataUpdated();

            qInfo() << "电表1数据：Ua=180V (跌落！)";
            qInfo() << "预期：触发A相电压跌落报警\n";

            QTimer::singleShot(2000, this, &AlarmEngineDemo::runStep);
            break;

        case 3:
            // 步骤3：测试去重（不应重复触发）
            qInfo() << "========================================";
            qInfo() << "[测试场景 3] 测试报警去重机制";
            qInfo() << "========================================";
            m_meter1->setUa(175.0); // 继续跌落
            emit m_meter1->dataUpdated();

            qInfo() << "电表1数据：Ua=175V (继续跌落)";
            qInfo() << "预期：不应重复触发报警（去重机制）\n";

            QTimer::singleShot(2000, this, &AlarmEngineDemo::runStep);
            break;

        case 4:
            // 步骤4：电压恢复
            qInfo() << "========================================";
            qInfo() << "[测试场景 4] 电压恢复正常";
            qInfo() << "========================================";
            m_meter1->setUa(220.0); // 恢复正常
            emit m_meter1->dataUpdated();

            qInfo() << "电表1数据：Ua=220V (恢复正常)";
            qInfo() << "预期：报警恢复\n";

            QTimer::singleShot(2000, this, &AlarmEngineDemo::runStep);
            break;

        case 5:
            // 步骤5：过流报警
            qInfo() << "========================================";
            qInfo() << "[测试场景 5] 模拟B相过流";
            qInfo() << "========================================";
            m_meter2->setUa(220.0);
            m_meter2->setUb(220.0);
            m_meter2->setUc(220.0);
            m_meter2->setIa(20.0);
            m_meter2->setIb(65.0); // 超过50A阈值
            m_meter2->setIc(20.0);
            emit m_meter2->dataUpdated();

            qInfo() << "电表2数据：Ib=65A (过流！)";
            qInfo() << "预期：触发B相过流报警\n";

            QTimer::singleShot(2000, this, &AlarmEngineDemo::runStep);
            break;

        case 6:
            // 步骤6：过压报警
            qInfo() << "========================================";
            qInfo() << "[测试场景 6] 模拟C相过压";
            qInfo() << "========================================";
            m_meter1->setUc(250.0); // 超过245V阈值
            emit m_meter1->dataUpdated();

            qInfo() << "电表1数据：Uc=250V (过压！)";
            qInfo() << "预期：触发C相过压报警\n";

            QTimer::singleShot(2000, this, &AlarmEngineDemo::runStep);
            break;

        case 7:
            // 步骤7：查询报警记录
            qInfo() << "========================================";
            qInfo() << "[测试场景 7] 查询报警记录";
            qInfo() << "========================================";
            {
                QDateTime endTime = QDateTime::currentDateTime();
                QDateTime startTime = endTime.addSecs(-3600); // 最近1小时

                QVector<AlarmRecord> records = DBManager::instance()->queryAlarmRecords(
                    -1, startTime, endTime);

                qInfo() << "查询到" << records.size() << "条报警记录：";
                for (const AlarmRecord &record : records)
                {
                    qInfo() << QString("  - [%1] 电表%2: %3 (值=%4, 阈值=%5) %6")
                                   .arg(record.id)
                                   .arg(record.meterId)
                                   .arg(record.alarmType)
                                   .arg(record.alarmValue)
                                   .arg(record.threshold)
                                   .arg(record.acknowledged ? "已确认" : "未确认");
                }
                qInfo() << "";
            }

            QTimer::singleShot(2000, this, &AlarmEngineDemo::runStep);
            break;

        case 8:
            // 步骤8：查看激活报警
            qInfo() << "========================================";
            qInfo() << "[测试场景 8] 当前激活的报警";
            qInfo() << "========================================";
            {
                QVector<AlarmEvent> activeAlarms = m_alarmEngine->getActiveAlarms();
                qInfo() << "当前有" << activeAlarms.size() << "个激活的报警：";
                for (const AlarmEvent &event : activeAlarms)
                {
                    qInfo() << "  -" << event.description();
                }
                qInfo() << "";
            }

            QTimer::singleShot(2000, this, &AlarmEngineDemo::runStep);
            break;

        case 9:
            // 步骤9：确认报警
            qInfo() << "========================================";
            qInfo() << "[测试场景 9] 确认报警";
            qInfo() << "========================================";
            {
                QVector<AlarmEvent> activeAlarms = m_alarmEngine->getActiveAlarms();
                if (!activeAlarms.isEmpty())
                {
                    int alarmId = activeAlarms.first().alarmId;
                    qInfo() << "确认报警 ID:" << alarmId;
                    m_alarmEngine->acknowledgeAlarm(alarmId);
                    qInfo() << "报警已确认\n";
                }
            }

            QTimer::singleShot(2000, this, &AlarmEngineDemo::runStep);
            break;

        case 10:
            // 步骤10：清理并退出
            qInfo() << "========================================";
            qInfo() << "[演示完成] 统计信息";
            qInfo() << "========================================";
            qInfo() << "总报警次数: " << m_alarmEngine->totalAlarmCount();
            qInfo() << "激活报警数: " << m_alarmEngine->activeAlarmCount();
            qInfo() << "未确认报警数: " << DBManager::instance()->getUnacknowledgedAlarmCount();
            qInfo() << "\n演示程序完成！\n";

            // 清理资源
            m_alarmEngine->stop();
            DBManager::instance()->close();

            QTimer::singleShot(1000, qApp, &QCoreApplication::quit);
            break;

        default:
            QCoreApplication::quit();
            break;
        }
    }

private:
    AlarmEngine *m_alarmEngine = nullptr;
    Meter *m_meter1 = nullptr;
    Meter *m_meter2 = nullptr;
    int m_step;
};

int main(int argc, char *argv[])
{
    QCoreApplication app(argc, argv);

    AlarmEngineDemo demo;
    demo.start();

    return app.exec();
}

#include "demo_alarmengine_usage.moc"
